package wxdb.ui;

import javax.swing.*;

import wxdb.metadata.TableMgr;
import wxdb.parse.*;
import wxdb.parse.absyn.*;
import wxdb.errmsg.ErrorMsg;
import wxdb.ui.Main;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;

public class UserIn extends JFrame{
	private File filein;
	private File filelexout;
	private File fileparout;
	
	private FileOutputStream flout;
	private FileOutputStream fin;
	private FileOutputStream fpout;
	
	private JMenuBar bar = new JMenuBar();
	
	private JMenu menuFile = new JMenu("File");
	private JMenu menuHelp = new JMenu("Help");
	
	private JMenuItem menuFileOpen = new JMenuItem("Open...");
	private JMenuItem menuFileSave = new JMenuItem("Save");
	private JMenuItem menuFileSaveAs = new JMenuItem("Save As ..");
	private JMenuItem menuFileQuit = new JMenuItem("Exit");
	
	private JMenuItem menuHelpAbout = new JMenuItem("About");
	
	private JButton beginButton = new JButton("Run");
	private JButton cleanButton = new JButton("Clean");
	
	private JLabel inputLabel = new JLabel("Input Code");
	private JLabel resultLabel = new JLabel("Lexer Result");
	
	private JTextArea inTextArea = new JTextArea(15,10);
	private JTextArea lexTextArea = new JTextArea(20,10);
	
	private JPanel pane = new JPanel();
	
	Font fon = new Font("Dialog",Font.PLAIN,15);
	
	
	private void initconter(){
		menuFile.add(menuFileOpen);
		menuFile.add(menuFileSave);
		menuFile.add(menuFileSaveAs);
		menuFile.addSeparator();
		menuFile.add(menuFileQuit);
		menuHelp.add(menuHelpAbout);
		
		bar.add(menuFile);
		bar.add(menuHelp);
	}
	
	
	void buildConstraints(GridBagConstraints gbc,int gx, int gy, int gw, int gh, int wx, int wy){
		gbc.gridx = gx;			
		gbc.gridy = gy;			
		gbc.gridwidth = gw;		
		gbc.gridheight = gh;	
		gbc.weightx = wx;		
		gbc.weighty = wy;		
	}
	
	
	private void setMyPane(){
		GridBagLayout gridbag = new GridBagLayout();
		GridBagConstraints constraints = new GridBagConstraints();
		pane.setLayout(gridbag);
		
		buildConstraints(constraints,0,0,2,1,10,1);
		constraints.fill = GridBagConstraints.VERTICAL;
		gridbag.setConstraints(inputLabel, constraints);
		pane.add(inputLabel);
		
		buildConstraints(constraints,2,0,2,1,10,1);
		gridbag.setConstraints(beginButton, constraints);
		pane.add(beginButton);
		
		JScrollPane inPane = new JScrollPane(inTextArea); 
		buildConstraints(constraints,0,1,4,1,5,200);
		constraints.fill = GridBagConstraints.BOTH;
		gridbag.setConstraints(inPane, constraints);
		inTextArea.setFont(fon);
		pane.add(inPane);
		
		lexTextArea.setEditable(false);
		lexTextArea.setBackground(Color.WHITE);
		JScrollPane outPane = new JScrollPane(lexTextArea);
		buildConstraints(constraints,4,1,3,1,5,200);
		gridbag.setConstraints(outPane, constraints);
		lexTextArea.setFont(fon);
		pane.add(outPane);
		
		buildConstraints(constraints,4,0,2,1,10,1);
		constraints.fill = GridBagConstraints.VERTICAL;
		gridbag.setConstraints(cleanButton, constraints);
		pane.add(cleanButton);
		
		buildConstraints(constraints,6,0,1,1,10,1);
		gridbag.setConstraints(resultLabel, constraints);
		pane.add(resultLabel);
		
		initconter();
		
		setJMenuBar(bar);
		setLocation(300,200);
		setContentPane(pane);
	}
	

	private void initListener(){
		ActListener actListener = new ActListener();
		menuFileOpen.addActionListener(actListener);
		menuFileQuit.addActionListener(actListener);
		menuHelpAbout.addActionListener(actListener);
		beginButton.addActionListener(actListener);
		cleanButton.addActionListener(actListener);
	}
	
	
	class ActListener implements ActionListener{
		public void actionPerformed(ActionEvent e){
			if(e.getSource() == menuFileOpen)
				openFile();
			if(e.getSource() == menuFileQuit)
				System.exit(0);
			if(e.getSource() == beginButton)
				porRun();
			if(e.getSource() == menuHelpAbout)
				JOptionPane.showMessageDialog(null, Global.VERSION, "About DBMS", JOptionPane.INFORMATION_MESSAGE);
			if(e.getSource() == cleanButton){
				inTextArea.setText("");
				lexTextArea.setText("");
			}
		}
	}

	
	private void openFile(){
		try{
			JFileChooser jFileChooser = new JFileChooser();
			jFileChooser.showOpenDialog(pane);
			String fileName = null;
			fileName = jFileChooser.getSelectedFile().getPath();
			File file = new File(fileName);
			int fLength;
			fLength = (int)file.length();
			int num = 0;
			FileReader fReader = new FileReader(file);
			char[] date = new char[fLength];
			while(fReader.ready()){
				num+=fReader.read(date,num,fLength-num);
			}
			fReader.close();
			inTextArea.setText(new String(date,0,num));
		}catch(IOException f){}
		
	}
	
	
	private void porRun(){
		try{
			RandomAccessFile rf = new RandomAccessFile("tmpin","rw");
			rf.setLength(0);
			rf.close();
		}catch(Exception e){};
		
		String inText = inTextArea.getText();
		filein = new File("tmpin");
		filelexout = new File("tmplexout");
		fileparout = new File("tmpparout");
		try{
			String result = new String("");
			String error = new String("");
			fin = new FileOutputStream(filein,false);
			flout = new FileOutputStream(filelexout,false);
			fpout = new FileOutputStream(fileparout,false);
			
			OutputStreamWriter writer = new OutputStreamWriter(fin);
			writer.write(inText);
			writer.close();
			
			
			ErrorMsg errMsg=new ErrorMsg("tmperr");
			Lexer lexer = new Yylex(filein,"tmperr",errMsg);
			
			Token tok;
			
			do { 
				tok=lexer.nextToken();
				if(Main.symnames[tok.sym].equals("error")){
					String r = new String("Line: "+tok.line+" "+tok.value+"\n");
					error+=r;
				}
				else{
					if(Main.symnames[tok.sym].equals("STRING")){
						String str = new String("Line: "+tok.line + "\tType: "+ Main.symnames[tok.sym] + "\tValue: \n" + tok.value + "\n");
						result+=str;
					}
					else if(Main.symnames[tok.sym].equals("FUNCTION") || Main.symnames[tok.sym].equals("SEMICOLON")){
						String t = new String("Line: "+tok.line + "\tType: "+ Main.symnames[tok.sym] + "Value: " + tok.value + "\n");
						result+=t;
					}
					else{
						String s = new String("Line: "+tok.line + "\tType: "+ Main.symnames[tok.sym] + "\tValue: " + tok.value + "\n");
						result+=s;
					}
				}
			} while (tok.sym != sym.EOF);
			

			
			writer = new OutputStreamWriter(flout);
			writer.write(result);
			writer.close();

			fin.close();
			flout.close();
			fpout.close();


		    File fileinin = new File("tmpin");
		    String temp="";
		    BufferedInputStream bis=new BufferedInputStream(new FileInputStream(fileinin));
		    byte b[]=new byte[1024*1024];
		    int length=bis.read(b);
		    temp=new String(b,0,length);
		    bis.close();  
		    String str[]=temp.split(";");
		    for(int i =0 ; i<str.length ;i++){
		    	System.out.println(str[i]);
		    	parser p = new parser(str[i]);
			    try{
			    	p.parse();
			    	Object o = p.parseResult;
			    	if (o instanceof QryExp){
			            HashMap<String,ArrayList> r = Global.planner().excuteQueryPlan((QryExp)o);
			            if(Global.GROUP_BY==true){
			            	r = TableMgr.groupBy(r,Global.group_by_field);
			            	if(Global.SUM == true){
			            		r = TableMgr.sumGroup(r,Global.computefield,Global.asfield);
			            		Global.SUM = false;
			            	}else if(Global.AVG == true){
			            		r = TableMgr.avgGroup(r,Global.computefield,Global.asfield);
			            		Global.AVG = false;
			            	}else if(Global.MAX == true){
			            		r = TableMgr.maxGroup(r,Global.computefield,Global.asfield);
			            		Global.MAX = false;
			            	}else if(Global.MIN == true){
			            		r = TableMgr.minGroup(r,Global.computefield,Global.asfield);
			            		Global.MIN = false;
			            	}else if(Global.COUNT == true){
			            		r = TableMgr.countGroup(r,Global.computefield,Global.asfield);
			            		Global.COUNT = false;
			            	}
			            	Global.computefield = "";
			            	Global.asfield = "";
			            	Global.GROUP_BY = false;
			            	Global.group_by_field = "";
			            }
			            if(Global.ORDER_BY==true){
			            	r = TableMgr.orderBy(r,Global.order_by_field);
			            	Global.ORDER_BY = false;
			            	Global.order_by_field = "";
			            }
			            new QueryResult(r);
			    	}
			    	else{
			    		Global.planner().executeUpdate(o);
			    	}
			    }catch(Exception err){
			    	System.err.println(err.getMessage());
			    }
		    }
   		
			String fileRName = new String("tmplexout");
			File filer = new File(fileRName);
			int fLength;
			fLength = (int)filer.length();
			int num = 0;
			FileReader fReader = new FileReader(filer);
			char[] date = new char[fLength];
			while(fReader.ready()){
				num+=fReader.read(date,num,fLength-num);
			}
			fReader.close();
			lexTextArea.setText(new String(date,0,num));
			
			String filePName = new String("tmpparout");
			File filep = new File(filePName);
			int pfLength;
			pfLength = (int)filep.length();
			num = 0;
			FileReader pfReader = new FileReader(filep);
			char[] pdate = new char[pfLength];
			while(pfReader.ready()){
				num+=pfReader.read(pdate,num,pfLength-num);
			}
			pfReader.close();
//			parseTextArea.setText(new String(pdate,0,num));
			
			
			
			String fileEName = new String("tmperr");
			File filee = new File(fileEName);
			fLength = (int)filee.length();
			int errnum = 0;
			FileReader fEReader = new FileReader(filee);
			char[] datee = new char[fLength];
			while(fEReader.ready()){
				errnum+=fEReader.read(datee,errnum,fLength-errnum);
			}
			fEReader.close();
		
			fin.close();
			flout.close();
			fpout.close();
		}catch(Exception e){};
	}
	
	public UserIn(){
		super(Global.VERSION);
		setSize(700,300);
//		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		initListener();
		setMyPane();
		setVisible(true);
		setResizable(false);
	}
}
